package com.tbit.main.controller;

import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.MachineOpLog;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.BatteryConstant;
import com.tbit.main.constant.ControlType;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.service.impl.MachineOpLogService;
import com.tbit.main.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 电池车辆绑定
 *
 * @author LMY
 * @create 2021-05-27 14:58
 */
@RestController
@RequestMapping("/batteryMachineController")
public class BatteryMachineController {

    @Autowired
    private BatteryMachineService batteryMachineService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private BatteryService batteryService;
    @Autowired
    private BatteryLogService batteryLogService;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private BatteryGroupBoundService batteryGroupBoundService;
    @Autowired
    private BatteryGroupService batteryGroupService;
    @Autowired
    private DataService dataService;
    @Autowired
    private MachineLoseService machineLoseService;
    @Autowired
    private MachineOpLogService machineOpLogService;

    /**
     * 出库
     */
    @RequestMapping("/batteryCK")
    public JsonResult batteryCK(String token, Integer accountId, String batteryNO, Integer type) {

        Assert.notNull(batteryNO, "Battery.batteryNO.notNull");
        Assert.notNull(type, "Battery.type.notNull");
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        AccountUser accountUser = tokenService.getAccount(token);

        batteryService.auth(accountUser.getAgents(), dataService.getBatteryId(batteryNO));

        /**出库*/
        if (type == 1) {
            Battery battery = batteryService.getByNO(batteryNO);

            if (!accountId.equals(battery.getAccountId())) {
                throw new BaseException("battery.userCode.notAccount");
            }

            /**判断出库*/
            if (!battery.getState().equals(BatteryConstant.Battery_State_KGZ)) {
                throw new BaseException("Battery.batteryNO.notCK");
            }

            batteryService.updateIdState(batteryNO, null, accountUser.getAccountUserId(), BatteryConstant.Battery_State_DCK, null);

            batteryLogService.insert(batteryNO, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_DCK, null);
        } else {

            /**判断取消出库*/
            Battery battery = batteryService.getByNO(batteryNO);

            if (!accountId.equals(battery.getAccountId())) {
                throw new BaseException("battery.userCode.notAccount");
            }

            if (!battery.getState().equals(BatteryConstant.Battery_State_DCK)) {
                throw new BaseException("Battery.batteryNO.notCK");
            }

            /**取消出库*/
            batteryService.updateIdState(batteryNO, null, accountUser.getAccountUserId(), BatteryConstant.Battery_State_KGZ, null);

            batteryLogService.insert(batteryNO, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_SCDCK, null);
        }

        return JsonResult.succ();
    }

    /**
     * 领取
     */
    @RequestMapping("/batteryLQ")
    public JsonResult batteryLQ(String token, Integer accountId, String batteryNO, Integer group) {

        Assert.notNull(batteryNO, "Battery.batteryNO.notNull");
        Assert.notNull(group, "Group.is.notNull");
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        /**判断领取*/
        Battery battery = batteryService.getByNO(batteryNO);
        if (!battery.getState().equals(BatteryConstant.Battery_State_DCK)) {
            throw new BaseException("Battery.batteryNO.notLQ");
        }

        if (!accountId.equals(battery.getAccountId())) {
            throw new BaseException("battery.userCode.notAccount");
        }

        AccountUser accountUser = tokenService.getAccount(token);

        batteryService.auth(accountUser.getAgents(), dataService.getBatteryId(batteryNO));

        /**领取分组所有*/
        List<BatteryGroupBound> batteryGroupBound = batteryGroupBoundService.getNOs(batteryNO);

        if (group == 1 && batteryGroupBound != null && batteryGroupBound.size() > 0) {
            List<String> batteryNOs = batteryGroupBound.stream().map(BatteryGroupBound::getBatteryNO).collect(Collectors.toList());

            batteryService.updateState(batteryNOs, accountUser.getAccountUserId(), BatteryConstant.Battery_State_WSY);

            batteryLogService.inserts(batteryNOs, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_LQ);

            batteryGroupService.del(batteryGroupBound.get(0).getId());

        } else {

            batteryService.updateIdState(batteryNO, null, accountUser.getAccountUserId(), BatteryConstant.Battery_State_WSY, null);

            batteryLogService.insert(batteryNO, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_LQ, null);

            batteryGroupBoundService.delBatteryNO(batteryNO);

            if (batteryGroupBound != null && batteryGroupBound.size() == 1) {
                batteryGroupService.del(batteryGroupBound.get(0).getId());
            }

        }

        return JsonResult.succ();
    }

    /**
     * 归还
     */
    @RequestMapping("/batteryGH")
    public JsonResult batteryGH(String token, String batteryNO, Integer type, Integer accountId) {

        Assert.notNull(batteryNO, "Battery.batteryNO.notNull");
        Assert.notNull(type, "Battery.type.notNull");
        Assert.notNull(accountId, "AccountUser.agentId.notNull");

        AccountUser accountUser = tokenService.getAccount(token);

        batteryService.auth(accountUser.getAgents(), dataService.getBatteryId(batteryNO));

        Battery battery = batteryService.getByNO(batteryNO);
        if (!battery.getState().equals(BatteryConstant.Battery_State_WSY) &&
                !battery.getState().equals(BatteryConstant.Battery_State_DRK)) {
            throw new BaseException("Battery.batteryNO.notGH");
        }


        if (!accountId.equals(battery.getAccountId())) {
            throw new BaseException("battery.userCode.notAccount");
        }


        /**单个归还*/
        if (type == 2) {

            batteryService.updateIdState(batteryNO, null, accountUser.getAccountUserId(), BatteryConstant.Battery_State_KGZ, null);

            batteryLogService.insert(batteryNO, battery.getAccountUserId(), BatteryConstant.Battery_Type_GH, null);

            batteryLogService.insert(batteryNO, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_RK, null);

        } else {
            /**批量归还*/

            List<Battery> batteries = batteryService.getByAccountIdReturn(battery.getState(), battery.getAccountUserId(), battery.getAccountId());

            List<String> batteryNOs = batteries.stream().map(Battery::getBatteryNO).collect(Collectors.toList());

            batteryService.updateState(batteryNOs, accountUser.getAccountUserId(), BatteryConstant.Battery_State_KGZ);

            batteryLogService.inserts(batteryNOs, battery.getAccountUserId(), BatteryConstant.Battery_Type_GH);

            batteryLogService.inserts(batteryNOs, accountUser.getAccountUserId(), BatteryConstant.Battery_Type_RK);

        }

        return JsonResult.succ();
    }

    /**
     * 换电接口
     */
    @RequestMapping("/change")
    public JsonResult change(String token, String userCode) {
        Assert.notNull(userCode, "Machine.userCode.notNull");

        AccountUser accountUserToken = tokenService.getAccount(token);

        /**触发删除用户检测*/
        AccountUser accountUserDB = accountUserService.getById(accountUserToken.getAccountUserId());
        if (accountUserDB == null) {
            /**删除token*/
            redisService.del(token);
            throw new BaseException("AccountUser.notExist");
        }

        /**查询设备信息*/
        Machine machine = machineService.getByUseCode(userCode);
        if (machine == null) {
            throw new BaseException("Machine.notExist");
        }

        MachineLose machineLose = machineLoseService.getAccountIdAndUserCode(machine.getAccountId(), machine.getUserCode());
        if (machineLose != null) {
            throw new BaseException("machine.lose.exit");
        }

        /**设备权限判断*/
        machineService.auth(accountUserToken.getAgents(), machine.getMachineId());

        /**生成流水号*/
        String serNO = UUID.randomUUID().toString();
        batteryMachineService.control(accountUserToken, serNO, machine, ControlType.MACHINE_CONTROL_BAT_UNLOCK);

        return JsonResult.succ(serNO);

    }

    /**
     * 确认换电
     */
    @RequestMapping("/changeCheck")
    public JsonResult changeCheck(String token, String userCode, String batteryNO, Integer mapType, Double lon, Double lat) {
        Assert.notNull(userCode, "Machine.userCode.notNull");
        Assert.notNull(batteryNO, "Battery.batteryNO.notNull");
        Assert.notNull(mapType, "Battery.type.notNull");
        Assert.notNull(lon, "System.lon.notNull");
        Assert.notNull(lat, "System.lat.notNull");

        AccountUser accountUser = tokenService.getAccount(token);

        /**设备权限判断*/
        Machine machine = machineService.getByUseCode(userCode);
        Battery battery = batteryService.getByNO(batteryNO);
        if (!machine.getAccountId().equals(battery.getAccountId())) {
            throw new BaseException("battery.userCode.notAccount");
        }
        machineService.auth(accountUser.getAgents(), machine.getMachineId());
        batteryService.auth(accountUser.getAgents(), dataService.getBatteryId(batteryNO));
        batteryMachineService.changeCheck(accountUser, userCode, batteryNO, mapType, lon, lat);

        return JsonResult.succ();
    }


    /**
     * 取消换电
     */
    @RequestMapping("/changeCancel")
    public JsonResult changeCancel(String token, String userCode, String remark) {

        AccountUser accountUser = tokenService.getAccount(token);

        batteryLogService.insert(null, accountUser.getAccountUserId(), BatteryConstant.battery_Type_QQHD, remark);
        return JsonResult.succ();
    }
}
